--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Node / ReticulumProjects / MeshChatX.git / files / tests / frontend / TutorialModalConnectBootstrap.test.js
Displaying Raw • Download
tests/frontend/TutorialModalConnectBootstrap.test.js b960db2e8bf87b96c14f6421402a16798d7a9ded (b960db2e) Text, 15.68 KB
T8b949e/* SPDX-License-Identifier: 0BSD */
T8b949e/**
* Adversarial / race oracles for tutorial connect + bootstrap flows.
* Each case states an invariant and asserts an exact postcondition.
*/
Tff7b72import Tb4b4b4{ Te6edf3describeTb4b4b4, Te6edf3itTb4b4b4, Te6edf3expectTb4b4b4, Te6edf3viTb4b4b4, Te6edf3beforeEachTb4b4b4, Te6edf3afterEach Tb4b4b4} Tff7b72from Ta5d6ff"vitest"Tb4b4b4;
Tff7b72import Tb4b4b4{ Te6edf3mountTb4b4b4, Te6edf3flushPromises Tb4b4b4} Tff7b72from Ta5d6ff"@vue/test-utils"Tb4b4b4;
Tff7b72import Tb4b4b4{ Te6edf3createRouterTb4b4b4, Te6edf3createWebHashHistory Tb4b4b4} Tff7b72from Ta5d6ff"vue-router"Tb4b4b4;
Tff7b72import Tb4b4b4{ Te6edf3createI18n Tb4b4b4} Tff7b72from Ta5d6ff"vue-i18n"Tb4b4b4;
Tff7b72import Tb4b4b4{ Te6edf3createVuetify Tb4b4b4} Tff7b72from Ta5d6ff"vuetify"Tb4b4b4;
Tff7b72import Te6edf3TutorialModal Tff7b72from Ta5d6ff"../../meshchatx/src/frontend/components/TutorialModal.vue"Tb4b4b4;
Tff7b72import Te6edf3en Tff7b72from Ta5d6ff"../../meshchatx/src/frontend/locales/en.json"Tb4b4b4;
Tff7b72import Te6edf3ToastUtils Tff7b72from Ta5d6ff"../../meshchatx/src/frontend/js/ToastUtils"Tb4b4b4;
Te6edf3viTb4b4b4.Te6edf3mockTb4b4b4(Ta5d6ff"../../meshchatx/src/frontend/js/GlobalState"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4(Tb4b4b4{
Tff7b72defaultTff7b72: Tb4b4b4{
Te6edf3configTff7b72: Tb4b4b4{ Te6edf3themeTff7b72: Ta5d6ff"light"Tb4b4b4, Te6edf3languageTff7b72: Ta5d6ff"en" Tb4b4b4}Tb4b4b4,
Te6edf3hasPendingInterfaceChangesTff7b72: Tff7b72falseTb4b4b4,
Te6edf3modifiedInterfaceNamesTff7b72: Tff7b72new Tffa657SetTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3viTb4b4b4.Te6edf3mockTb4b4b4(Ta5d6ff"../../meshchatx/src/frontend/js/ToastUtils"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4(Tb4b4b4{
Tff7b72defaultTff7b72: Tb4b4b4{
Te6edf3successTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3errorTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3warningTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3infoTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3viTb4b4b4.Te6edf3mockTb4b4b4(Ta5d6ff"../../meshchatx/src/frontend/js/DialogUtils"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4(Tb4b4b4{
Tff7b72defaultTff7b72: Tb4b4b4{
Te6edf3confirmTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3axiosMock Tff7b72= Tb4b4b4{ Te6edf3getTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3postTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3patchTff7b72: Te6edf3viTb4b4b4.Te6edf3fnTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4;
Tff7b72const Te6edf3vuetify Tff7b72= Te6edf3createVuetifyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3i18n Tff7b72= Te6edf3createI18nTb4b4b4(Tb4b4b4{
Te6edf3legacyTff7b72: Tff7b72falseTb4b4b4,
Te6edf3localeTff7b72: Ta5d6ff"en"Tb4b4b4,
Te6edf3messagesTff7b72: Tb4b4b4{ Te6edf3en Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3dialogStubs Tff7b72= Tb4b4b4{
Te6edf3LanguageSelectorTff7b72: Tff7b72trueTb4b4b4,
Te6edf3MaterialDesignIconTff7b72: Tff7b72trueTb4b4b4,
Te6edf3ToggleTff7b72: Tff7b72trueTb4b4b4,
Te6edf3TutorialPrivacyStepTff7b72: Tff7b72trueTb4b4b4,
Te6edf3VIconTff7b72: Tb4b4b4{ Te6edf3templateTff7b72: Ta5d6ff'<span class="v-icon-stub"/>' Tb4b4b4}Tb4b4b4,
Te6edf3VProgressCircularTff7b72: Tb4b4b4{ Te6edf3templateTff7b72: Ta5d6ff'<span class="progress-stub"/>' Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4;
Tff7b72function Te6edf3tcpCommunityTb4b4b4(Te6edf3nTb4b4b4) Tb4b4b4{
Tff7b72return Tffa657ArrayTb4b4b4.Tff7b72fromTb4b4b4(Tb4b4b4{ Te6edf3lengthTff7b72: Te6edf3n Tb4b4b4}Tb4b4b4, Tb4b4b4(Te6edf3_Tb4b4b4, Te6edf3iTb4b4b4) Tb4b4b4=> Tb4b4b4(Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff`Ta5d6ffNode Tffd700${Te6edf3i Tff7b72+ T79c0ff1Tffd700}Ta5d6ff`Tb4b4b4,
Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4,
Te6edf3target_hostTff7b72: Ta5d6ff`Ta5d6ff10.0.0.Tffd700${Te6edf3i Tff7b72+ T79c0ff1Tffd700}Ta5d6ff`Tb4b4b4,
Te6edf3target_portTff7b72: T79c0ff4242 Tff7b72+ Te6edf3iTb4b4b4,
Te6edf3descriptionTff7b72: Ta5d6ff"community tcp"Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72function Te6edf3apiHandlersTb4b4b4(Te6edf3communityInterfaces Tff7b72= Tb4b4b4[Tb4b4b4]Tb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4(Te6edf3urlTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3url Tff7b72=== Ta5d6ff"/api/v1/app/info"Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3app_infoTff7b72: Tb4b4b4{ Te6edf3migrationTff7b72: Tb4b4b4{ Te6edf3show_choiceTff7b72: Tff7b72false Tb4b4b4} Tb4b4b4} Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3url Tff7b72=== Ta5d6ff"/api/v1/reticulum/discovery"Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3discoveryTff7b72: Tb4b4b4{ Te6edf3default_bootstrap_onlyTff7b72: Tff7b72false Tb4b4b4} Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3url Tff7b72=== Ta5d6ff"/api/v1/community-interfaces"Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3interfacesTff7b72: Te6edf3communityInterfaces Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3url Tff7b72=== Ta5d6ff"/api/v1/reticulum/discovered-interfaces"Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3interfacesTff7b72: Tb4b4b4[Tb4b4b4]Tb4b4b4, Te6edf3activeTff7b72: Tb4b4b4[Tb4b4b4] Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3url Tff7b72=== Ta5d6ff"/api/v1/config"Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3configTff7b72: Tb4b4b4{ Te6edf3display_nameTff7b72: Ta5d6ff"Anonymous Peer" Tb4b4b4} Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3url Tff7b72=== Ta5d6ff"/api/v1/identities"Tb4b4b4) Tb4b4b4{
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{
Te6edf3dataTff7b72: Tb4b4b4{
Te6edf3identitiesTff7b72: Tb4b4b4[Tb4b4b4{ Te6edf3hashTff7b72: Ta5d6ff"default_identity"Tb4b4b4, Te6edf3display_nameTff7b72: Ta5d6ff"Anonymous Peer"Tb4b4b4, Te6edf3is_currentTff7b72: Tff7b72true Tb4b4b4}Tb4b4b4]Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Tffa657PromiseTb4b4b4.Te6edf3resolveTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4;
Tb4b4b4}
Tff7b72async Tff7b72function Te6edf3mountTutorialTb4b4b4(Te6edf3communityInterfaces Tff7b72= Te6edf3tcpCommunityTb4b4b4(T79c0ff6Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3axiosMockTb4b4b4.Te6edf3getTb4b4b4.Te6edf3mockImplementationTb4b4b4(Te6edf3apiHandlersTb4b4b4(Te6edf3communityInterfacesTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3axiosMockTb4b4b4.Te6edf3postTb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3messageTff7b72: Ta5d6ff"ok" Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3axiosMockTb4b4b4.Te6edf3patchTb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3messageTff7b72: Ta5d6ff"ok" Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3router Tff7b72= Te6edf3createRouterTb4b4b4(Tb4b4b4{
Te6edf3historyTff7b72: Te6edf3createWebHashHistoryTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3routesTff7b72: Tb4b4b4[Tb4b4b4{ Te6edf3pathTff7b72: Ta5d6ff"/"Tb4b4b4, Te6edf3nameTff7b72: Ta5d6ff"home"Tb4b4b4, Te6edf3componentTff7b72: Tb4b4b4{ Te6edf3templateTff7b72: Ta5d6ff"<div/>" Tb4b4b4} Tb4b4b4}Tb4b4b4]Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3routerTb4b4b4.Te6edf3pushTb4b4b4(Ta5d6ff"/"Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3routerTb4b4b4.Te6edf3isReadyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3wrapper Tff7b72= Te6edf3mountTb4b4b4(Te6edf3TutorialModalTb4b4b4, Tb4b4b4{
Te6edf3attachToTff7b72: Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4,
Tffa657globalTff7b72: Tb4b4b4{ Te6edf3pluginsTff7b72: Tb4b4b4[Te6edf3routerTb4b4b4, Te6edf3vuetifyTb4b4b4, Te6edf3i18nTb4b4b4]Tb4b4b4, Te6edf3stubsTff7b72: Te6edf3dialogStubs Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3showTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Te6edf3wrapperTb4b4b4;
Tb4b4b4}
Te6edf3describeTb4b4b4(Ta5d6ff"TutorialModal connect/bootstrap adversarial oracles"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3beforeEachTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tffa657windowTb4b4b4.Te6edf3api Tff7b72= Te6edf3axiosMockTb4b4b4;
Te6edf3viTb4b4b4.Te6edf3clearAllMocksTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3afterEachTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3viTb4b4b4.Te6edf3useRealTimersTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H1: footer must not expose Finish Setup on connect or bootstrap steps"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72const Te6edf3step Tff7b72of Tb4b4b4[T79c0ff3Tb4b4b4, T79c0ff4Tb4b4b4]Tb4b4b4) Tb4b4b4{
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= Te6edf3stepTb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3$nextTickTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3showFooterContinueTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72=== Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3totalStepsTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3finishButtons Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3findAllTb4b4b4(Ta5d6ff"button"Tb4b4b4)Tb4b4b4.Te6edf3filterTb4b4b4(Tb4b4b4(Te6edf3bTb4b4b4) Tb4b4b4=> Te6edf3bTb4b4b4.Te6edf3textTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3includesTb4b4b4(Te6edf3enTb4b4b4.Te6edf3tutorialTb4b4b4.Te6edf3finish_setupTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3finishButtonsTb4b4b4.Te6edf3lengthTb4b4b4, Ta5d6ff`Ta5d6fffinish visible on step Tffd700${Te6edf3stepTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H2: nextStep with recommended mode must enter bootstrap step 4 not skip to 5"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff3Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionMode Tff7b72= Ta5d6ff"recommended"Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3nextStepTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStepTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H3: previousStep from propagation after recommended returns to bootstrap step 4"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionMode Tff7b72= Ta5d6ff"recommended"Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff5Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3previousStepTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStepTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H4: concurrent auto pickRandom must not interleave (second call no-ops while busy)"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Te6edf3tcpCommunityTb4b4b4(T79c0ff8Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff4Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionMode Tff7b72= Ta5d6ff"discovery"Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3communityInterfaces Tff7b72= Te6edf3tcpCommunityTb4b4b4(T79c0ff8Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3shuffleSpy Tff7b72= Te6edf3viTb4b4b4.Te6edf3spyOnTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4, Ta5d6ff"shuffleArrayInPlace"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3p1 Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickRandomTcpBootstrapsTb4b4b4(Tb4b4b4{ Te6edf3silentTff7b72: Tff7b72trueTb4b4b4, Te6edf3autoTff7b72: Tff7b72trueTb4b4b4, Te6edf3countTff7b72: T79c0ff3 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickingRandomBootstrapsTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3p2 Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickRandomTcpBootstrapsTb4b4b4(Tb4b4b4{ Te6edf3silentTff7b72: Tff7b72trueTb4b4b4, Te6edf3autoTff7b72: Tff7b72trueTb4b4b4, Te6edf3countTff7b72: T79c0ff3 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Tffa657PromiseTb4b4b4.Te6edf3allTb4b4b4(Tb4b4b4[Te6edf3p1Tb4b4b4, Te6edf3p2Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3shuffleSpyTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledTimesTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeysTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickingRandomBootstrapsTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H5: useDiscoveryMode resets auto-pick latch so a second visit can pick again"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Te6edf3tcpCommunityTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff3Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3bootstrapAutoPickDone Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeys Tff7b72= Tb4b4b4[Tb4b4b4]Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3communityInterfaces Tff7b72= Te6edf3tcpCommunityTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3useDiscoveryModeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3$nextTickTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStepTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionModeTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"discovery"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickingRandomBootstrapsTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeysTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3bootstrapAutoPickDoneTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H5b: watcher must not mark auto-pick done when pick is already in flight"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Te6edf3tcpCommunityTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff4Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionMode Tff7b72= Ta5d6ff"discovery"Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3bootstrapAutoPickDone Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeys Tff7b72= Tb4b4b4[Tb4b4b4]Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3communityInterfaces Tff7b72= Te6edf3tcpCommunityTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickingRandomBootstraps Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3maybeAutoPickBootstrapTcpTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3bootstrapAutoPickDoneTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeysTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H6: useRecommendedMode adds AutoInterface, enables discovery, picks exactly 3 TCP"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Te6edf3tcpCommunityTb4b4b4(T79c0ff7Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff3Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3useRecommendedModeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3axiosMockTb4b4b4.Te6edf3postTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(Ta5d6ff"/api/v1/reticulum/interfaces/add"Tb4b4b4, Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"Local Network"Tb4b4b4,
Te6edf3typeTff7b72: Ta5d6ff"AutoInterface"Tb4b4b4,
Te6edf3enabledTff7b72: Tff7b72trueTb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3axiosMockTb4b4b4.Te6edf3patchTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(
Ta5d6ff"/api/v1/reticulum/discovery"Tb4b4b4,
Te6edf3expectTb4b4b4.Te6edf3objectContainingTb4b4b4(Tb4b4b4{
Te6edf3discover_interfacesTff7b72: Tff7b72trueTb4b4b4,
Te6edf3autoconnect_discovered_interfacesTff7b72: T79c0ff3Tb4b4b4,
Tb4b4b4}Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStepTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionModeTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"recommended"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeysTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeysTb4b4b4.Te6edf3everyTb4b4b4(Tb4b4b4(Te6edf3kTb4b4b4) Tb4b4b4=> Te6edf3kTb4b4b4.Te6edf3startsWithTb4b4b4(Ta5d6ff"comm:"Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3addingRecommendedTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H7: connection mode buttons stay locked while discovery is in flight"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72let Te6edf3resolvePatchTb4b4b4;
Te6edf3axiosMockTb4b4b4.Te6edf3getTb4b4b4.Te6edf3mockImplementationTb4b4b4(Te6edf3apiHandlersTb4b4b4(Te6edf3tcpCommunityTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3axiosMockTb4b4b4.Te6edf3patchTb4b4b4.Te6edf3mockImplementationTb4b4b4(
Tb4b4b4(Tb4b4b4) Tb4b4b4=>
Tff7b72new Tffa657PromiseTb4b4b4(Tb4b4b4(Te6edf3resolveTb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3resolvePatch Tff7b72= Te6edf3resolveTb4b4b4;
Tb4b4b4}Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3axiosMockTb4b4b4.Te6edf3postTb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3router Tff7b72= Te6edf3createRouterTb4b4b4(Tb4b4b4{
Te6edf3historyTff7b72: Te6edf3createWebHashHistoryTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3routesTff7b72: Tb4b4b4[Tb4b4b4{ Te6edf3pathTff7b72: Ta5d6ff"/"Tb4b4b4, Te6edf3nameTff7b72: Ta5d6ff"home"Tb4b4b4, Te6edf3componentTff7b72: Tb4b4b4{ Te6edf3templateTff7b72: Ta5d6ff"<div/>" Tb4b4b4} Tb4b4b4}Tb4b4b4]Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3routerTb4b4b4.Te6edf3pushTb4b4b4(Ta5d6ff"/"Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3routerTb4b4b4.Te6edf3isReadyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3wrapper Tff7b72= Te6edf3mountTb4b4b4(Te6edf3TutorialModalTb4b4b4, Tb4b4b4{
Te6edf3attachToTff7b72: Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4,
Tffa657globalTff7b72: Tb4b4b4{ Te6edf3pluginsTff7b72: Tb4b4b4[Te6edf3routerTb4b4b4, Te6edf3vuetifyTb4b4b4, Te6edf3i18nTb4b4b4]Tb4b4b4, Te6edf3stubsTff7b72: Te6edf3dialogStubs Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3showTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff3Tb4b4b4;
Tff7b72const Te6edf3pending Tff7b72= Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3useDiscoveryModeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3$nextTickTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionSetupBusyTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3tutorialNavBusyTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
T8b949e// Adversarial second click must not start another discovery patch
Tff7b72const Te6edf3patchCallsBefore Tff7b72= Te6edf3axiosMockTb4b4b4.Te6edf3patchTb4b4b4.Te6edf3mockTb4b4b4.Te6edf3callsTb4b4b4.Te6edf3lengthTb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3useDiscoveryModeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3useRecommendedModeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3useLocalModeTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3axiosMockTb4b4b4.Te6edf3patchTb4b4b4.Te6edf3mockTb4b4b4.Te6edf3callsTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3patchCallsBeforeTb4b4b4)Tb4b4b4;
Te6edf3resolvePatchTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3messageTff7b72: Ta5d6ff"ok" Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3pendingTb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionSetupBusyTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H8: skip/confirm bootstraps are ignored while random pick is busy"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Te6edf3tcpCommunityTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff4Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionMode Tff7b72= Ta5d6ff"discovery"Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickingRandomBootstraps Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeys Tff7b72= Tb4b4b4[Ta5d6ff"comm:Node 1"Tb4b4b4]Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3skipBootstrapsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStepTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3confirmBootstrapsTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStepTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff4Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3axiosMockTb4b4b4.Te6edf3postTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toHaveBeenCalledWithTb4b4b4(
Ta5d6ff"/api/v1/reticulum/interfaces/add"Tb4b4b4,
Te6edf3expectTb4b4b4.Te6edf3objectContainingTb4b4b4(Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"Node 1" Tb4b4b4}Tb4b4b4)
Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H9: yggdrasil / ygg-labelled community presets are excluded from random pick"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3mixed Tff7b72= Tb4b4b4[
Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"Yggdrasil Bridge"Tb4b4b4,
Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4,
Te6edf3target_hostTff7b72: Ta5d6ff"1.1.1.1"Tb4b4b4,
Te6edf3target_portTff7b72: T79c0ff4242Tb4b4b4,
Te6edf3descriptionTff7b72: Ta5d6ff"ygg only"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"Normal A"Tb4b4b4,
Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4,
Te6edf3target_hostTff7b72: Ta5d6ff"2.2.2.2"Tb4b4b4,
Te6edf3target_portTff7b72: T79c0ff4242Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"Normal B"Tb4b4b4,
Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4,
Te6edf3target_hostTff7b72: Ta5d6ff"3.3.3.3"Tb4b4b4,
Te6edf3target_portTff7b72: T79c0ff4242Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"Normal C"Tb4b4b4,
Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4,
Te6edf3target_hostTff7b72: Ta5d6ff"4.4.4.4"Tb4b4b4,
Te6edf3target_portTff7b72: T79c0ff4242Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4{
Te6edf3nameTff7b72: Ta5d6ff"Normal D"Tb4b4b4,
Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4,
Te6edf3target_hostTff7b72: Ta5d6ff"5.5.5.5"Tb4b4b4,
Te6edf3target_portTff7b72: T79c0ff4242Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Te6edf3mixedTb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3communityInterfaces Tff7b72= Te6edf3mixedTb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickRandomTcpBootstrapsTb4b4b4(Tb4b4b4{ Te6edf3silentTff7b72: Tff7b72trueTb4b4b4, Te6edf3autoTff7b72: Tff7b72trueTb4b4b4, Te6edf3countTff7b72: T79c0ff3 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeysTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"comm:Yggdrasil Bridge"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeysTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H10: random pick prefers at most available eligible nodes and never selects hostless entries"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3sparse Tff7b72= Tb4b4b4[
Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"Good1"Tb4b4b4, Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4, Te6edf3target_hostTff7b72: Ta5d6ff"8.8.8.8"Tb4b4b4, Te6edf3target_portTff7b72: T79c0ff4242 Tb4b4b4}Tb4b4b4,
Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"NoHost"Tb4b4b4, Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4, Te6edf3target_hostTff7b72: Ta5d6ff""Tb4b4b4, Te6edf3target_portTff7b72: T79c0ff4242 Tb4b4b4}Tb4b4b4,
Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"UDP"Tb4b4b4, Te6edf3typeTff7b72: Ta5d6ff"UDPInterface"Tb4b4b4, Te6edf3target_hostTff7b72: Ta5d6ff"9.9.9.9"Tb4b4b4, Te6edf3target_portTff7b72: T79c0ff4242 Tb4b4b4}Tb4b4b4,
Tb4b4b4{ Te6edf3nameTff7b72: Ta5d6ff"Good2"Tb4b4b4, Te6edf3typeTff7b72: Ta5d6ff"TCPClientInterface"Tb4b4b4, Te6edf3target_hostTff7b72: Ta5d6ff"8.8.4.4"Tb4b4b4, Te6edf3target_portTff7b72: T79c0ff4242 Tb4b4b4}Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Te6edf3sparseTb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3communityInterfaces Tff7b72= Te6edf3sparseTb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3pickRandomTcpBootstrapsTb4b4b4(Tb4b4b4{ Te6edf3countTff7b72: T79c0ff99 Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3selectedBootstrapKeysTb4b4b4.Te6edf3sortTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toEqualTb4b4b4(Tb4b4b4[Ta5d6ff"comm:Good1"Tb4b4b4, Ta5d6ff"comm:Good2"Tb4b4b4]Tb4b4b4.Te6edf3sortTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H11: useRecommendedMode failure after AutoInterface add does not advance step"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3axiosMockTb4b4b4.Te6edf3getTb4b4b4.Te6edf3mockImplementationTb4b4b4(Te6edf3apiHandlersTb4b4b4(Te6edf3tcpCommunityTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3axiosMockTb4b4b4.Te6edf3postTb4b4b4.Te6edf3mockResolvedValueTb4b4b4(Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3messageTff7b72: Ta5d6ff"added" Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3axiosMockTb4b4b4.Te6edf3patchTb4b4b4.Te6edf3mockRejectedValueTb4b4b4(Tb4b4b4{ Te6edf3responseTff7b72: Tb4b4b4{ Te6edf3dataTff7b72: Tb4b4b4{ Te6edf3messageTff7b72: Ta5d6ff"discovery failed" Tb4b4b4} Tb4b4b4} Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3router Tff7b72= Te6edf3createRouterTb4b4b4(Tb4b4b4{
Te6edf3historyTff7b72: Te6edf3createWebHashHistoryTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3routesTff7b72: Tb4b4b4[Tb4b4b4{ Te6edf3pathTff7b72: Ta5d6ff"/"Tb4b4b4, Te6edf3nameTff7b72: Ta5d6ff"home"Tb4b4b4, Te6edf3componentTff7b72: Tb4b4b4{ Te6edf3templateTff7b72: Ta5d6ff"<div/>" Tb4b4b4} Tb4b4b4}Tb4b4b4]Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3routerTb4b4b4.Te6edf3pushTb4b4b4(Ta5d6ff"/"Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3routerTb4b4b4.Te6edf3isReadyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3wrapper Tff7b72= Te6edf3mountTb4b4b4(Te6edf3TutorialModalTb4b4b4, Tb4b4b4{
Te6edf3attachToTff7b72: Tffa657documentTb4b4b4.Te6edf3bodyTb4b4b4,
Tffa657globalTff7b72: Tb4b4b4{ Te6edf3pluginsTff7b72: Tb4b4b4[Te6edf3routerTb4b4b4, Te6edf3vuetifyTb4b4b4, Te6edf3i18nTb4b4b4]Tb4b4b4, Te6edf3stubsTff7b72: Te6edf3dialogStubs Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3showTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff3Tb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3useRecommendedModeTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72await Te6edf3flushPromisesTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStepTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3connectionModeTb4b4b4)Tb4b4b4.Te6edf3toBeNullTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3addingRecommendedTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3ToastUtilsTb4b4b4.Te6edf3errorTb4b4b4)Tb4b4b4.Te6edf3toHaveBeenCalledTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H12: theme/language controls are in-flow (not absolute overlay) so titles are not covered"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3findTb4b4b4(Ta5d6ff".absolute.top-4.left-4"Tb4b4b4)Tb4b4b4.Te6edf3existsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3findTb4b4b4(Ta5d6ff".absolute.top-4.right-4"Tb4b4b4)Tb4b4b4.Te6edf3existsTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Te6edf3itTb4b4b4(Ta5d6ff"H13: double finishTutorial is race-safe while connect busy"Tb4b4b4, Tff7b72async Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3wrapper Tff7b72= Tff7b72await Te6edf3mountTutorialTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3currentStep Tff7b72= T79c0ff3Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3savingDiscovery Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72await Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3finishTutorialTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3visibleTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3wrapperTb4b4b4.Te6edf3vmTb4b4b4.Te6edf3finishingTutorialTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3wrapperTb4b4b4.Te6edf3unmountTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────